home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fatted Calf
/
The Fatted Calf.iso
/
Applications
/
Graphics
/
nxyplot
/
Source
/
ErrorBarHandler.m
< prev
next >
Wrap
Text File
|
1992-07-20
|
11KB
|
358 lines
/* Generated by Interface Builder */
#import "ErrorBarHandler.h"
#import "Plot.h"
#import "defs.h"
#import <appkit/Font.h>
#import <appkit/Panel.h>
#import <appkit/Window.h>
#import <appkit/Matrix.h>
#import <appkit/View.h>
#import <appkit/ButtonCell.h>
#import <dpsclient/wraps.h>
#import <appkit/color.h> /* only for "blanking out" parts of a matrix */
#import <appkit/graphics.h> /* ditto */
/*
* The job of this object is to keep the appearance of the Error Bar panel in
* accord with the state of the program. This is only needed if the Error Bar
* panel is visible. A lot of the code is the same as in ColumnSelectionHandler.m.
*/
@implementation ErrorBarHandler
- init
{
/*
* This global variable keeps track of whether the error bar window
* has ever been displayed. We can avoid updating after the selective
* file removal if we have never been displayed.
*/
everVisible = NO;
return self;
}
- eraseDisabledCells:sender
{
int n, j, numrows, numcols, ncurves;
NXRect r;
BOOL exbars, eybars;
[errorBarMatrix getNumRows:&numrows numCols:&numcols];
[errorBarMatrix lockFocus];
NXSetColor([errorBarMatrix backgroundColor]); /* cf. comment in ColumnSelectionHandler.m */
for (n=0; n<[plotParam nFiles]; n++) {
exbars = [plotParam has_exbars:n];
eybars = [plotParam has_eybars:n];
if (!exbars && !eybars) {
/* if this file has no error bars, blank out everything */
for (j=-1; j<numcols; j++) {
[errorBarMatrix getCellFrame:&r at:n :j+1]; /* note the j+1 here and below */
NXRectFill(&r);
}
}
else if (exbars && !eybars) {
/* x error bars, no y error bars, blank out some columns */
for (j=0; j<numcols; j++) {
[errorBarMatrix getCellFrame:&r at:n :j+1];
NXRectFill(&r);
}
}
else if (!exbars && eybars) {
/* no x error bars, has y error bars; blank out 1st and some more columns */
[errorBarMatrix getCellFrame:&r at:n :0];
NXRectFill(&r);
ncurves = [plotParam nCurves:n];
if (ncurves < numcols) {
for (j=ncurves; j<numcols; j++) {
[errorBarMatrix getCellFrame:&r at:n :j+1];
NXRectFill(&r);
}
}
}
else {
/* both x and y error bars; maybe blank out some columns */
ncurves = [plotParam nCurves:n];
if (ncurves < numcols) {
for (j=ncurves; j<numcols; j++) {
[errorBarMatrix getCellFrame:&r at:n :j+1];
NXRectFill(&r);
}
}
}
}
[errorBarMatrix unlockFocus];
NXPing();
return self;
}
- removeAll:sender
/* This method is called by the "remove all files" method of the Plot object. */
{
int n, j;
int numrows, numcols;
NXSize cellsize, intercell;
NXCoord dy;
/* Do something only if the window has ever been displayed */
if (everVisible) {
[errorBarMatrix getNumRows:&numrows numCols:&numcols];
[errorBarMatrix getCellSize:&cellsize];
[errorBarMatrix getIntercell:&intercell];
/*
* Wipe out everything.
*/
dy = (NXCoord)(numrows - 1) * (cellsize.height + intercell.height);
[errorBarMatrix moveBy:0.0 :dy];
/*
* Before doing renewRows, set the state of all the cells to 1; this is
* because the renewRows method just recycles the cells, and later on
* we may find ourselves using a cell which has state=0 when we don't
* want such a beast. Also disable all cells (paranoia strikes).
*/
for (n=0; n<numrows; n++) {
for (j=0; j<numcols; j++) {
[[errorBarMatrix cellAt:n :j] setState:1];
[[errorBarMatrix cellAt:n :j] setEnabled:YES];
}
}
[errorBarMatrix renewRows:1 cols:1];
[errorBarMatrix sizeToCells];
[[errorBarMatrix cellAt:0 :0] setType:NX_TOGGLE];
[filenameMatrix moveBy:0.0 :dy];
[filenameMatrix renewRows:1 cols:1];
[[filenameMatrix cellAt:0 :0] setStringValue:"filename"];
[filenameMatrix sizeToCells];
[errorBarText renewRows:1 cols:1];
[errorBarText sizeToCells];
/* Do some drawing now. Display the view. */
[[errorBarMatrix window] display];
NXPing(); /* needed??? */
}
return self;
}
- updatePanel:sender
/*
* The update button activates this method; it is also called from
* windowDidResize and from Plot.m in postludeToReading. We have to
* fix up the error bar panel so that it's correct.
*/
{
int n, j;
int nfilestotal = [plotParam nFiles], maxcols = 0, ncurves;
char title[80];
int numrows, numcols;
NXSize cellsize, intercell;
NXCoord dy;
int ** turned_on;
BOOL exbars, eybars;
if (everVisible == NO) everVisible = YES;
[errorBarMatrix getNumRows:&numrows numCols:&numcols];
[errorBarMatrix getCellSize:&cellsize];
[errorBarMatrix getIntercell:&intercell];
/*
* We have to create some additional rows and perhaps some additional columns.
*/
// First figure out how many columns the matrix should have
for (n=0; n<nfilestotal; n++) {
maxcols = MAX(maxcols, [plotParam nCurves:n]);
}
maxcols++; /* add one column for the "x" (zero) column */
if (numrows != nfilestotal || numcols != maxcols) {
/* The renewRows:cols: message might have the side effect of setting
* the state of all the cells of the matrix back to 0; this is undesired,
* so before changing the number of rows and/or columns in the matrix,
* make sure we remember which cells in each row were turned on.
*/
turned_on = (int **)malloc(nfilestotal * sizeof(int)); /* should do error check */
for (n=0; n<nfilestotal; n++) {
*(turned_on + n) = (int *)malloc(maxcols * sizeof(int));
}
for (n=0; n<nfilestotal; n++) {
for (j=0; j<maxcols; j++) {
*(*(turned_on+n)+j) = 1;
}
}
for (n=0; n<numrows; n++) {
for (j=0; j<numcols; j++) {
*(*(turned_on+n)+j) = [[errorBarMatrix cellAt:n :j] state];
}
}
[errorBarMatrix renewRows:nfilestotal cols:maxcols];
for (n=0; n<nfilestotal; n++) {
for (j=0; j<maxcols; j++) {
[[errorBarMatrix cellAt:n :j] setState:1]; /* everything turned on */
}
}
/* Turn cells off if needed. */
for (n=0; n<numrows; n++) {
for (j=0; j<numcols; j++) {
[[errorBarMatrix cellAt:n :j] setState:*(*(turned_on+n)+j)];
}
}
for (n=0; n<nfilestotal; n++) {
free((void *)*(turned_on + n));
}
free((void *)turned_on);
}
[errorBarMatrix sizeToCells];
dy = (float)(nfilestotal - numrows) * (cellsize.height + intercell.height);
[errorBarMatrix moveBy:0.0 :-dy];
// Some of the cells may come in with type NULLCELL; fix them here
for (n=0; n<nfilestotal; n++) {
for (j=0; j<maxcols; j++) {
[[errorBarMatrix cellAt:n :j] setEnabled:YES];
[[errorBarMatrix cellAt:n :j] setType:NX_TOGGLE];
}
}
// We surround the [errorBarMatrix display] and [self eraseDisabledCells]
// calls with the disableFlushWindow, reenableFlushWindow, and flushWindow
// calls to prevent the disabled matrix cells from being visible for a long
// time while they're drawn and then erased.
[errorBarPanel disableFlushWindow];
[errorBarMatrix display];
// Disable cells that shouldn't appear.
for (n=0; n<nfilestotal; n++) {
exbars = [plotParam has_exbars:n];
eybars = [plotParam has_eybars:n];
if (!exbars && !eybars) {
/* if this file has no error bars, disable everything */
for (j=-1; j<maxcols; j++) {
[[errorBarMatrix cellAt:n :j+1] setType:NX_NULLCELL];
[[errorBarMatrix cellAt:n :j+1] setEnabled:NO];
}
}
else if (exbars && !eybars) {
/* x error bars, no y error bars, blank out some columns */
for (j=0; j<numcols; j++) {
[[errorBarMatrix cellAt:n :j+1] setType:NX_NULLCELL];
[[errorBarMatrix cellAt:n :j+1] setEnabled:NO];
}
}
else if (!exbars && eybars) {
/* no x error bars, has y error bars; blank out 1st and some more columns */
[[errorBarMatrix cellAt:n :0] setType:NX_NULLCELL];
[[errorBarMatrix cellAt:n :0] setEnabled:NO];
ncurves = [plotParam nCurves:n];
if (ncurves < numcols) {
for (j=ncurves; j<maxcols; j++) {
[[errorBarMatrix cellAt:n :j+1] setType:NX_NULLCELL];
[[errorBarMatrix cellAt:n :j+1] setEnabled:NO];
}
}
}
else {
/* both x and y error bars; maybe blank out some columns */
ncurves = [plotParam nCurves:n];
if (ncurves < numcols) {
for (j=ncurves; j<numcols; j++) {
[[errorBarMatrix cellAt:n :j+1] setType:NX_NULLCELL];
[[errorBarMatrix cellAt:n :j+1] setEnabled:NO];
}
}
}
}
// We have to put the makeKeyAndOrderFront before the eraseDisabledCells
// method, because eraseDisabledCells does a lockFocus and lockFocus needs
// a real window to draw into. We put the makeKeyAndOrderFront here rather
// than at the beginning of this method because this way the disabled cells
// of the matrix are visible for a shorter period of time.
[errorBarPanel makeKeyAndOrderFront:self];
// Now erase those disabled cells.
[self eraseDisabledCells:self];
[errorBarPanel reenableFlushWindow];
[errorBarPanel flushWindowIfNeeded];
NXPing(); /* needed? */
// That finishes with the errorBarMatrix; now for the filename Matrix.
[filenameMatrix renewRows:nfilestotal cols:1];
for (n=0; n<nfilestotal; n++) {
if (!strncmp([plotParam filename:(unsigned)n], "pasteboard", 10))
sprintf(title, "pasteboard");
else
sprintf(title, strrchr([plotParam filename:(unsigned)n], '/') + 1);
[[filenameMatrix cellAt:n :0] setStringValue:title];
}
[filenameMatrix sizeToCells];
[filenameMatrix moveBy:0.0 :-dy];
[filenameMatrix display];
// And now for the errorBarText matrix.
[errorBarText renewRows:1 cols:maxcols];
for (j=0; j<maxcols; j++) {
sprintf(title, "%d", j);
[[errorBarText cellAt:0 :j] setStringValue:title];
}
[errorBarText sizeToCells];
[errorBarText display];
return self;
}
/*
* Apropos this, see the remarks in ColumnSelectionHandler.m
*/
- windowDidResize:sender
{
[self perform:@selector(updatePanel:)
with:self
afterDelay:1 /* wait 0.001 second */
cancelPrevious:YES];
return self;
}
/*
* This is called by the selective file removal code in Plot.m.
*/
- update:sender
{
int n, nfilestotal = [plotParam nFiles], num_removed = 0;
NXSize cellsize, intercell;
NXCoord dy;
/* Do something only if the window has ever been displayed */
if (everVisible) {
[errorBarMatrix getCellSize:&cellsize];
[errorBarMatrix getIntercell:&intercell];
/*
* Count down the file removal panel, removing rows as needed.
*/
for (n = nfilestotal-1; n>=0; n--) {
if ([[fileRemovalButtons cellAt:n :0] state] == 1) {
/* This file is to be removed. */
num_removed++;
[errorBarMatrix removeRowAt:n andFree:YES];
[filenameMatrix removeRowAt:n andFree:YES];
}
}
[errorBarMatrix sizeToCells];
[filenameMatrix sizeToCells];
if (num_removed > 0) {
dy = (NXCoord)(num_removed) * (cellsize.height + intercell.height);
[errorBarMatrix moveBy:0.0 :dy];
[filenameMatrix moveBy:0.0 :dy];
}
/* Do some drawing now. Display the view. */
[[errorBarMatrix window] display];
NXPing(); /* needed??? */
}
return self;
}
@end